<!DOCTYPE html>
<script>
  if (window.internals)
    internals.settings.setViewportMetaEnabled(true);
</script>
<script src="../../../resources/testharness.js"></script>
<script src="../../../resources/testharnessreport.js"></script>

<meta name="viewport" content="width=980">

<style>
  html {
    width: 100%;
    height: 100%;
    background-color: white;
  }
  body {
    width: 100%;
    height: 100%;
    background-color: lightgrey;
    margin: 0;
  }
  #widediv {
    border: 5px solid black;
    box-sizing: border-box;
    width: 200%;
  }
  #target {
    width: 300px;
    height: 300px;
    position: absolute;
    top: 600%;
    background-color: red;
    margin-bottom: 600%;
  }
  p {
    margin-top: 0;
  }
</style>
<p>
  This test verifies that intersection observer on the root is correct in the
  presence of Android's quirky viewport mode when an element wider than the
  initial contianing block is present. The light grey box represents the
  initial contianing block. The wide black box ensures the page is zoomed out
  further than the ICB.
</p>

<p>
  To test manually: Scroll down until you see the box. This test passes if, as
  soon as the box intersects the viewport, it turns green.
</p>
<div id="widediv"></div>
<div id="target"></div>

<script>
  const box = document.getElementById("target");
  const targetTop = box.getBoundingClientRect().top;
  const targetBottom = box.getBoundingClientRect().bottom;

  const viewportHeight = window.innerHeight;
  const startIntersectingScrollTop = targetTop - viewportHeight;
  const endIntersectingScrollTop = targetBottom;

  function isVisible() {
    return window.scrollY >= startIntersectingScrollTop &&
           window.scrollY < targetBottom;
  }

  function scrollToAndWaitFrame(y) {
    return () => {
      return new Promise((resolve) => {
        window.scrollTo(0, y);
        requestAnimationFrame(() => {
          resolve();
        });
      });
    };
  }

  addEventListener("load", () => {
    if (window.internals)
      internals.setPageScaleFactor(0.5);

    promise_test( t => {
      return new Promise((resolve, reject) => {
        if (window.testRunner)
          assert_equals(visualViewport.scale, 0.5, "Page must start zoomed out");

        const callback = function(entries) {
          if (window.testRunner) {
            t.step(() => {
              assert_equals(entries.length, 1, "Observing only one element");
              assert_equals(entries[0].isIntersecting, isVisible(),
                  "Report intersection only if element is on-screen");
            });
          }
          box.style.backgroundColor =
              entries[0].isIntersecting ? "green" : "red";
        };
        const observer = new IntersectionObserver(callback, {});
        observer.observe(box);
        resolve();
      })
      .then(scrollToAndWaitFrame(startIntersectingScrollTop - 1))
      .then(scrollToAndWaitFrame(startIntersectingScrollTop + 1))
      .then(scrollToAndWaitFrame(endIntersectingScrollTop - 1))
      .then(scrollToAndWaitFrame(endIntersectingScrollTop + 1));
    }, "IntersectionObserver uses correct root box");
  });
</script>
